﻿using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using ZXW.DotNet.Common.Basic.Network.Udp;

namespace Lootom.Proxy.Agent
{
    internal class SnmpProxy
    {
        private Socket _socket;
        private EndPoint _sourceIpAddress;
        private UDPSimple _udpSimple = new UDPSimple(123);

        public SnmpProxy(IPEndPoint targetIpAddress, int localPort)
        {
            TargetIpAddress = targetIpAddress;
            LocalPort = localPort;
            TimeOut = 5;
        }

        public IPEndPoint TargetIpAddress { get; set; }
        public int LocalPort { get; set; }
        public bool IsRunning { get; set; }
        public int TimeOut { get; set; }

        public void Star()
        {
            if (IsRunning)
                return;
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            var ipep = new IPEndPoint(IPAddress.Any, LocalPort);
            var ep = (EndPoint) ipep;
            _socket.Bind(ep);
            _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
            IsRunning = true;
            var thread = new Thread(new ThreadStart(ReceiveCallback));
            thread.Start();
        }

        private void ReceiveCallback()
        {
            var buff = new byte[1024*16];
            EndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 0);
            int count = _socket.ReceiveFrom(buff, ref ipEndPoint);
            Debug.WriteLine(buff);
            if (count > 0)
            {
                if (!ipEndPoint.Equals(TargetIpAddress))
                {
                    _sourceIpAddress = ipEndPoint;
                    if (TargetIpAddress != null)
                        _socket.SendTo(buff, 0, count, SocketFlags.None, TargetIpAddress);
                }
                else
                {
                    _socket.SendTo(buff, 0, count, SocketFlags.None, _sourceIpAddress);
                }
            }
            ReceiveCallback();
        }

        public void Stop()
        {
            _socket.Close();
            _socket.Dispose();
        }
    }
}